﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using Mjollnir;
using System;

namespace Test.Mjollnir
{
    [TestClass]
    public class ThrowTest
    {
        [TestMethod]
        public void IfTest1()
        {
            var message = "Hello, world.";

            Throw<Exception>.If(false);
            Throw<Exception>.If(false, message);
        }

        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void IfTest2()
        {
            Throw<Exception>.If(true);
        }

        [TestMethod]
        [ExpectedException(typeof(Exception))]
        public void IfTest3()
        {
            var message = "Hello, world.";

            try
            {
                Throw<Exception>.If(true, message);
            }
            catch (Exception x)
            {
                var expected = message;
                var actual = x.Message;

                Assert.AreEqual(expected, actual);
                throw;
            }
        }

        [TestMethod]
        public void IfNullTest1()
        {
            var param = new object();
            var paramName = "param";
            var message = "Hello, world.";

            Throw.IfNull(param, paramName);
            Throw.IfNull(param, paramName, message);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void IfNullTest2()
        {
            var param = default(object);
            var paramName = "param";

            try
            {
                Throw.IfNull(param, paramName);
            }
            catch (ArgumentNullException x)
            {
                var expected = paramName;
                var actual = x.ParamName;

                Assert.AreEqual(expected, actual);
                throw;
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void IfNullTest3()
        {
            var param = default(object);
            var paramName = "param";
            var message = "Hello, world.";

            try
            {
                Throw.IfNull(param, paramName, message);
            }
            catch (ArgumentNullException x)
            {
                {
                    var expected = paramName;
                    var actual = x.ParamName;

                    Assert.AreEqual(expected, actual);
                }

                {
                    var expected = message;
                    var actual = x.Message;

                    Assert.IsTrue(actual.IndexOf(expected) == 0);
                }
                throw;
            }
        }


        [TestMethod]
        public void IfOutOfRangeTest1()
        {
            var param = 1;
            var paramName = "param";
            var message = "Hello, world.";

            Throw.IfOutOfRange(0 < param && param < 10, paramName);
            Throw.IfOutOfRange(0 < param && param < 10, paramName, message);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void IfOutOfRangeTest2()
        {
            var param = -1;
            var paramName = "param";

            try
            {
                Throw.IfOutOfRange(0 < param && param < 10, paramName);
            }
            catch (ArgumentOutOfRangeException x)
            {
                var expected = paramName;
                var actual = x.ParamName;

                Assert.AreEqual(expected, actual);
                throw;
            }
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void IfOutOfRangeTest3()
        {
            var param = -1;
            var paramName = "param";
            var message = "Hello, world.";

            try
            {
                Throw.IfOutOfRange(0 < param && param < 10, paramName, message);
            }
            catch (ArgumentOutOfRangeException x)
            {
                {
                    var expected = paramName;
                    var actual = x.ParamName;

                    Assert.AreEqual(expected, actual);
                }

                {
                    var expected = message;
                    var actual = x.Message;

                    Assert.IsTrue(actual.IndexOf(expected) == 0);
                }
                throw;
            }
        }
    }
}
